package com.spzx.product.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.common.core.utils.bean.BeanUtils;
import com.spzx.product.api.domain.vo.CategoryVo;
import com.spzx.product.domain.Category;
import com.spzx.product.domain.vo.CategoryExcelVo;
import com.spzx.product.helper.CategoryHelper;
import com.spzx.product.mapper.CategoryMapper;
import com.spzx.product.service.ICategoryService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * 商品分类Service业务层处理
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    @Override
    public List<Category> treeSelect(Long parentId) {
        List<Category> categoryList = categoryMapper.selectList(new LambdaQueryWrapper<Category>()
                .eq(Category::getParentId, parentId));

        if (!CollectionUtils.isEmpty(categoryList)) {

            for (Category category : categoryList) {
                // TODO 需要优化处理
                Long count = categoryMapper.selectCount(new LambdaQueryWrapper<Category>()
                        .eq(Category::getParentId, category.getId()));
                category.setHasChildren(count>0);

            }

        }
        return categoryList;
    }

    /*@Override
    public List<Category> treeSelect(Long parentId) {
        List<Category> categoryList = categoryMapper.selectList(new LambdaQueryWrapper<Category>()
                .eq(Category::getParentId, parentId));

        if (!CollectionUtils.isEmpty(categoryList)) {

            List<Long> categoryIdList = categoryList.stream().map(Category::getId).toList();
            List<Category> categoryChildrenList = categoryMapper
                    .selectList(new LambdaQueryWrapper<Category>().in(Category::getParentId, categoryIdList)
                            .select(Category::getParentId, Category::getId));

            Map<Long, List<Category>> idToCategoryListMap = categoryChildrenList
                    .stream().collect(Collectors.groupingBy(Category::getParentId));

            for (Category category : categoryList) {
                List<Category> childrenList = idToCategoryListMap.get(category.getId());
                if(childrenList!=null && childrenList.size()>0) {
                    category.setHasChildren(true);
                }else{
                    category.setHasChildren(false);
                }
            }
        }
        return categoryList;
    }*/

    @Override
    public List<Long> getAllCategoryIdList(Long id) {
        List<Long> idList = new ArrayList<>();  //[1,2,3]  正序

        //存储顺序：逆序
        List<Category> categoryList = this.getParentCategoryList(id, new ArrayList<Category>()); // [c3,c2,c1]
        int size = categoryList.size();
        for (int i = size - 1; i >= 0; i--) {
            Category category = categoryList.get(i);
            idList.add(category.getId());
        }
        return idList;
    }

    /**
     * 递归：根据本级分类id,查询本级分类及所有上级分类数据；存储，逆序
     * 1.三级找二级、二级找一级 过程是同样过程
     * 2.一级找父亲没有了就结束了。
     *
     * @param id
     * @param categoryList
     * @return
     */
    private List<Category> getParentCategoryList(Long id, ArrayList<Category> categoryList) {
        while (id > 0) {
            Category category = categoryMapper.selectById(id); //本级
            categoryList.add(category);
            return getParentCategoryList(category.getParentId(), categoryList);
        }
        return categoryList;
    }


    @Override
    public void exportExcel(HttpServletResponse response) {
        try {
            //1.设置响应内容类型和编码
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");

            //2.设置响应头信息,响应位置，即：以附件形式打开文件。客户端弹出另存为窗口（不同浏览器行为不一样，可能直接下载，不弹出另存为窗口）。
            String fileName = URLEncoder.encode("分类数据", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); //下载
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

            //3.查询分类集合数据，进行类型转换
            List<Category> categoryList = this.list();
            List<CategoryExcelVo> categoryExcelVoList = categoryList.stream().map(item -> {
                CategoryExcelVo vo = new CategoryExcelVo();
                BeanUtils.copyProperties(item, vo);
                return vo;
            }).toList();

            //4.导出数据到Excel，用响应流返回给客户端。
            EasyExcel.write(response.getOutputStream(),CategoryExcelVo.class).sheet("商品分类").doWrite(categoryExcelVoList);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    @Override
    public void importData(MultipartFile file) throws Exception {
        //1.从请求输入流中读上传Excel文件的数据，数据封装成List<CategoryExcelVo>
        List<CategoryExcelVo> categoryExcelVoList = EasyExcel.read(file.getInputStream()).head(CategoryExcelVo.class).sheet().doReadSync();

        //2.进行类型转换List<CategoryExcelVo>  -> List<Category>
        List<Category> categoryList = categoryExcelVoList.stream().map(item -> {
            Category category = new Category();
            BeanUtils.copyProperties(item, category);
            return category;
        }).toList();


        //3.批量保存
        this.saveBatch(categoryList); // 默认批量 1000
    }


    @Override
    public List<CategoryVo> getOneCategory() {
        List<Category> oneCategoryAllList = categoryMapper.selectList(new LambdaQueryWrapper<Category>().eq(Category::getParentId, 0));
        return oneCategoryAllList.stream().map(item -> {
            CategoryVo vo = new CategoryVo();
            BeanUtils.copyProperties(item, vo);
            return vo;
        }).toList();
    }


    @Override
    public List<CategoryVo> tree() {
        //1.查询所有分类数据
        List<CategoryVo> categoryVoList = new ArrayList<>(); // 703条

        //2.进行类型转换
        List<Category> categoryAllList = this.list(); // 703条
        if(!CollectionUtils.isEmpty(categoryAllList)){
            for (Category category : categoryAllList) {
                CategoryVo vo = new CategoryVo();
                BeanUtils.copyProperties(category,vo);
                categoryVoList.add(vo);
            }
        }
        //3.构建树结构，组装父子关系
        List<CategoryVo> treeVoList = CategoryHelper.buildTree(categoryVoList);
        //4.返回组装好的父子关系集合
        return treeVoList;
    }
}